package com.tmc.platform.ctrip.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.tmc.constant.OrderConstant;
import com.tmc.constant.OrderConstant.OrderSource;
import com.tmc.entity.intair.IntairFare;
import com.tmc.entity.intair.IntairFlight;
import com.tmc.entity.intair.IntairOrder;
import com.tmc.entity.intair.IntairPassenger;
import com.tmc.entity.intair.IntairSegment;
import com.tmc.platform.ctrip.bean.IssueBillDetailInfo;
import com.tmc.platform.ctrip.bean.OpenIssueBillDetailResponse;
import com.tmc.platform.ctrip.bean.OpenIssueBillInfoResponse;
import com.tmc.platform.ctrip.bean.OpenIssueBillResponse;
import com.tmc.util.DateUtil;
import com.tmc.util.ObjectUtil;

public class CtripOrderUtil {

	public static IntairOrder toSysOrder(OpenIssueBillResponse ctripOrder) {
		IntairOrder order = new IntairOrder();
		order.setSource(OrderSource.INTERFACE.getSource());
		order.setPlatform(OrderConstant.PLATFORM_CTRIP);
		order.setAdtk(DateUtil.toLongDate(ctripOrder.getAdtk()));
		order.setLpnr(ctripOrder.getAirlineRecodeNo());
		order.setCreationDate(DateUtil.toLongDate(ctripOrder.getDataChange_CreateTime()));
		order.setLastUpdateDate(DateUtil.toLongDate(ctripOrder.getDataChange_LastTime()));
		order.setPlatformOrderNum(ctripOrder.getIssueBillID() + "");
		order.setMemo(ctripOrder.getIssueRemark());
		order.setTicketingType(ctripOrder.getIssueWay());
		order.setTicketingDeadline(DateUtil.toLongDate(ctripOrder.getLastPrintTicketTime()));
		order.setOfficeNo(ctripOrder.getOfficeNo());
		order.setPlatformPolicyId(ctripOrder.getPolicyID() + "");
		order.setPnr(ctripOrder.getRecodeNo());
		order.setTicketingType(ctripOrder.getTicketType());
		order.setCreatedBy(-1L);
		order.setBookDate(DateUtil.toLongDate(ctripOrder.getOrderDate()));
		//
		Map<String, List<OpenIssueBillDetailResponse>> map = getDetailListMap(ctripOrder);
		List<IntairPassenger> passengers = getPassengers(map);
		List<IntairFlight> flights = getFlights(map);
		order.setPassengers(passengers);
		order.setFlights(flights);
		return order;
	}
	
	public static IntairOrder toSysOrder(OpenIssueBillInfoResponse ctripOrder) {
		IntairOrder order = new IntairOrder();
		order.setSource(OrderSource.INTERFACE.getSource());
		order.setPlatform(OrderConstant.PLATFORM_CTRIP);
		order.setAdtk(DateUtil.toLongDate(ctripOrder.getAdtk()));
		order.setLpnr(ctripOrder.getAirlineRecodeNo());
		order.setCreationDate(DateUtil.toLongDate(ctripOrder.getTBookingDateTime()));
		order.setPlatformOrderNum(ctripOrder.getIssueBillID() + "");
		order.setMemo(ctripOrder.getIssueRemark());
		order.setTicketingType(ctripOrder.getIssueWay());
		order.setTicketingDeadline(DateUtil.toLongDate(ctripOrder.getLastPrintTicketTime()));
		order.setOfficeNo(ctripOrder.getOfficeNO());
		order.setPlatformPolicyId(ctripOrder.getPolicyID() + "@" + ctripOrder.getPolicyType() + "@" + ctripOrder.getPolicyCode());
		order.setPnr(ctripOrder.getRecordNO());
		order.setTicketType(ctripOrder.getTicketType() + "");
		order.setCreatedBy(-1L);
		order.setFlightType(ctripOrder.getFlightWay());
		order.setEiRemark(ctripOrder.getEIRemark());
		order.setPlatformStatus(ctripOrder.getIssueStatus() + "");
		//order.setBookDate(DateUtil.toLongDate(ctripOrder.getOrderDate()));
		//
		Map<String, List<IssueBillDetailInfo>> map = getDetailListMap1(ctripOrder);
		List<IntairPassenger> passengers = getPassengers1(map);
		List<IntairFlight> flights = getFlights1(map);
		order.setPassengers(passengers);
		order.setFlights(flights);
		return order;
	}
	
	private static Map<String, List<IssueBillDetailInfo>> getDetailListMap1(OpenIssueBillInfoResponse ctripOrder){
		List<IssueBillDetailInfo> details = ctripOrder.getIssueBillDetailInfoList();
		Map<String, List<IssueBillDetailInfo>> map = new HashMap<String, List<IssueBillDetailInfo>>();
		for (IssueBillDetailInfo detail : details) {
			String cardNo = detail.getCardNo();
			if (map.containsKey(cardNo)) {
				List<IssueBillDetailInfo> list = map.get(cardNo);
				list.add(detail);
			} else {
				List<IssueBillDetailInfo> list = new ArrayList<IssueBillDetailInfo>();
				list.add(detail);
				map.put(cardNo, list);
			}
		}
		return map;
	}
	
	private static List<IntairPassenger> getPassengers1(Map<String, List<IssueBillDetailInfo>> map) {
		List<IntairPassenger> passengers = new ArrayList<IntairPassenger>();
		for (List<IssueBillDetailInfo> list : map.values()) {
			passengers.add(getPassenger1(list));
		}
		return passengers;
	}
	
	private static IntairPassenger getPassenger1(List<IssueBillDetailInfo> list) {
		IntairPassenger passenger = new IntairPassenger();
		IssueBillDetailInfo detail = list.get(0);
		passenger.setPassengerType(getPassengerType(detail.getAgeType()));
		passenger.setBirthday(detail.getBirthDate());
		passenger.setCardNum(detail.getCardNo());
		passenger.setCardDate(detail.getCardTimelimit());
		passenger.setCardType(detail.getCardTypeInt() + "");
		passenger.setGender(detail.getGender());
		passenger.setNationality(detail.getNationality());
		passenger.setPassengerNameEn(detail.getPassengerName());
		passenger.setFirstName(detail.getPassengerName().split("/")[0]);
		passenger.setLastName(detail.getPassengerName().split("/")[1]);
		IntairFare fare = new IntairFare();
		Double ticketPrice = 0D;
		Double tax = 0D;
		for (IssueBillDetailInfo one : list) {
			ticketPrice += one.getPrintPrice();
			tax += one.getTax();
		}
		fare.setTicketPrice(ticketPrice);
		fare.setTax(tax);
		fare.setTotalAmount(ticketPrice + tax);
		fare.setTicketNum(detail.getTicketNO());
		passenger.setFare(fare);
		return passenger;
	}
	
	private static String getPassengerType (String type) {
		if (ObjectUtil.noText(type) || "ADU".equals(type)) {
			return OrderConstant.PASSENGER_TYPE_ADT;
		}
		if ("CHI".equals(type)) {
			return OrderConstant.PASSENGER_TYPE_CHD;
		}
		return type;
	}
	
	private static List<IntairFlight> getFlights1(Map<String, List<IssueBillDetailInfo>> map) {
		List<IssueBillDetailInfo> list = map.values().iterator().next();
		List<IntairSegment> segments = new ArrayList<IntairSegment>();
		for (IssueBillDetailInfo detail : list) {
			segments.add(getSegment1(detail));
		}
		return buildFlights(segments);
	}
	
	private static IntairSegment getSegment1(IssueBillDetailInfo detail) {
		IntairSegment segment = new IntairSegment();
		segment.setArrivalCity(detail.getACity());
		segment.setArrival(detail.getAPort());
		String arrivalTime = detail.getArrivalTime();
		segment.setArrivalDate(arrivalTime.split("T")[0]);
		segment.setArrivalTime(arrivalTime.split("T")[1].substring(0, 5));
		segment.setBookingCodeClass(detail.get_Class());
		segment.setBookingCode(detail.getSubClass());
		segment.setDepartureCity(detail.getDCity());
		segment.setDeparture(detail.getDPort());
		String departTime = detail.getTakeOffTime();
		segment.setDepartureDate(departTime.split("T")[0]);
		segment.setDepartureTime(departTime.split("T")[1].substring(0, 5));
		try {
			String flightNo = detail.getFlight();
			segment.setAirline(flightNo.substring(0, 2));
			segment.setFlightNo(flightNo.substring(2));
		}catch(Exception e) {
			
		}
		segment.setSegmentIndex(detail.getSequence());
		return segment;
	}

	private static Map<String, List<OpenIssueBillDetailResponse>> getDetailListMap(OpenIssueBillResponse ctripOrder){
		List<OpenIssueBillDetailResponse> details = ctripOrder.getBillDetailList();
		Map<String, List<OpenIssueBillDetailResponse>> map = new HashMap<String, List<OpenIssueBillDetailResponse>>();
		for (OpenIssueBillDetailResponse detail : details) {
			String cardNo = detail.getCardNo();
			if (map.containsKey(cardNo)) {
				List<OpenIssueBillDetailResponse> list = map.get(cardNo);
				list.add(detail);
			} else {
				List<OpenIssueBillDetailResponse> list = new ArrayList<OpenIssueBillDetailResponse>();
				list.add(detail);
				map.put(cardNo, list);
			}
		}
		return map;
	}

	private static List<IntairFlight> getFlights(Map<String, List<OpenIssueBillDetailResponse>> map) {
		List<OpenIssueBillDetailResponse> list = map.values().iterator().next();
		List<IntairSegment> segments = new ArrayList<IntairSegment>();
		for (OpenIssueBillDetailResponse detail : list) {
			segments.add(getSegment(detail));
		}
		return buildFlights(segments);
	}
	
	private static IntairSegment getSegment(OpenIssueBillDetailResponse detail) {
		IntairSegment segment = new IntairSegment();
		segment.setArrivalCity(detail.getACity());
		segment.setArrival(detail.getAPort());
		String arrivalTime = detail.getArrivalTime();
		segment.setArrivalDate(arrivalTime.split("T")[0]);
		segment.setArrivalTime(arrivalTime.split("T")[1].substring(0, 5));
		segment.setBookingCodeClass(detail.get_Class());
		segment.setBookingCode(detail.getSubClass());
		segment.setCreationDate(DateUtil.toLongDate(detail.getDateChange_CreateTime()));
		segment.setLastUpdateDate(DateUtil.toLongDate(detail.getDataChange_LastTime()));
		segment.setDepartureCity(detail.getDCity());
		segment.setDeparture(detail.getDPort());
		String departTime = detail.getTakeOffTime();
		segment.setDepartureDate(departTime.split("T")[0]);
		segment.setDepartureTime(departTime.split("T")[1].substring(0, 5));
		String flightNo = detail.getFlight();
		segment.setAirline(flightNo.substring(0, 2));
		segment.setFlightNo(flightNo.substring(2));
		segment.setSegmentIndex(detail.getSequence());
		return segment;
	}

	private static List<IntairPassenger> getPassengers(Map<String, List<OpenIssueBillDetailResponse>> map) {
		List<IntairPassenger> passengers = new ArrayList<IntairPassenger>();
		for (List<OpenIssueBillDetailResponse> list : map.values()) {
			passengers.add(getPassenger(list));
		}
		return passengers;
	}
	
	private static IntairPassenger getPassenger(List<OpenIssueBillDetailResponse> list) {
		IntairPassenger passenger = new IntairPassenger();
		OpenIssueBillDetailResponse detail = list.get(0);
		passenger.setPassengerType(getPassengerType(detail.getAgeType()));
		passenger.setBirthday(detail.getBirthDate());
		passenger.setCardNum(detail.getCardNo());
		passenger.setCardDate(detail.getCardTimelimit());
		passenger.setCardType(detail.getCardType() + "");
		passenger.setGender(detail.getGender());
		passenger.setNationality(detail.getNationality());
		passenger.setPassengerNameEn(detail.getPassengerName());
		passenger.setFirstName(detail.getPassengerName().split("/")[0]);
		passenger.setLastName(detail.getPassengerName().split("/")[1]);
		IntairFare fare = new IntairFare();
		Double ticketPrice = 0D;
		Double tax = 0D;
		for (OpenIssueBillDetailResponse one : list) {
			ticketPrice += one.getPrintPrice();
			tax += one.getTax();
		}
		fare.setTicketPrice(ticketPrice);
		fare.setTax(tax);
		fare.setTotalAmount(ticketPrice + tax);
		passenger.setFare(fare);
		return passenger;
	}
	
	public static List<IntairFlight> buildFlights(List<IntairSegment> segments) {
		Collections.sort(segments, new Comparator<IntairSegment>() {
			@Override
			public int compare(IntairSegment arg0, IntairSegment arg1) {
				return arg0.getSegmentIndex().compareTo(arg1.getSegmentIndex());
			}
		});
		List<IntairFlight> flights = new ArrayList<IntairFlight>();
		IntairSegment lastSegment = null;
		for (IntairSegment segment : segments) {
			if (lastSegment == null || !isSameFlight(lastSegment, segment)) {
				IntairFlight flight = new IntairFlight();
				flight.setSegments(new ArrayList<IntairSegment>());
				flight.getSegments().add(segment);
				flights.add(flight);
			} else {
				flights.get(flights.size() - 1).getSegments().add(segment);
			}
			lastSegment = segment;
		}
		Integer flightIndex = 1;
		for (IntairFlight flight : flights) {
			flight.setFlightIndex(flightIndex++);
			Integer segIndex = 1;
			for (IntairSegment segment : flight.getSegments()) {
				if (segIndex == 1) {
					flight.setDeparture(segment.getDeparture());
					flight.setAirline(segment.getAirline());
					flight.setDepartureDate(segment.getDepartureDate());
					flight.setDepartureTime(segment.getDepartureTime());
				}
				if (segIndex == flight.getSegments().size()) {
					flight.setArrival(segment.getArrival());
					flight.setArrivalDate(segment.getArrivalDate());
					flight.setArrivalTime(segment.getArrivalTime());
				}
				segment.setSegmentIndex(segIndex++);
			}
		}
		return flights;
	}
	
	private static boolean isSameFlight(IntairSegment lastSegment, IntairSegment segment) {
		try {
			String arriTime = lastSegment.getDepartureDate() + lastSegment.getArrivalTime();
			String departTime = segment.getDepartureDate() + segment.getDepartureTime();
			if (DateUtil.toLongDate(DateUtil.addDate(DateUtil.format(arriTime, "yyyy-MM-ddHH:mm"), 1)) < DateUtil
					.toLongDate(DateUtil.format(departTime, "yyyy-MM-ddHH:mm"))) {
				return false;
			}
		} catch (Exception e) {
			return false;
		}
		return true;
	}
}
